/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package PhysicCollection;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JPanel;

/**
 *
 * @author danh.ngothanh
 */
public class BidaDemo extends JPanel implements MouseListener, MouseMotionListener, Runnable{

    private double starttime, shottime, currenttime, acceleration, velocity, velocityangle, velocitypower;
    private int holddistancex, holddistancey, distancex, distancey, ballx, bally, oldballx, oldbally, ballradius, lineparamA, lineparamB, lineparamC;
    private boolean isrunning, isholding, isshoted, direction, directionx, directiony;
    public BidaDemo(){
        starttime = 0;
        shottime = 0;
        currenttime = 0;
        acceleration = 0;
        velocityangle = 0;
        velocity = 0;
        velocitypower = 0;
        holddistancex = 0;
        holddistancey = 0;
        ballx = 50;
        bally = 400;
        oldballx = ballx;
        oldbally = bally;
        ballradius = 25;
        isholding = false;
        isshoted = false;
        isrunning = true;
        distancex = 0;
        distancey = 0;
        direction = true;//move theo x
        directionx = true;//tang x
        directiony = true;//tang y
    }

    public void init(){
        addMouseListener(this);
        addMouseMotionListener(this);       
    }
    
    public void createlinefuntion(int xa, int ya, int xb, int yb){
        lineparamA = (yb - ya);
        lineparamB = (-1)*(xb - xa);
        lineparamC = ((-1)*(yb - ya)*(xa) + (xb - xa)*ya);
    }
    public int recalculatey(int newx){
        int returny = 0;
        if(lineparamB != 0)
            returny = (int)((-1)*lineparamA*newx - lineparamC)/lineparamB;        
        return returny;        
    }
    public int recalculatex(int newy){
        int returnx = 0;
        if(lineparamA != 0)
            returnx = (int)((-1)*lineparamB*newy- lineparamC)/lineparamA;
        return returnx;
    }

    @Override
    public void paint(Graphics g){
        g.setColor(new Color(50, 100, 100));
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.BLACK);
        g.drawString("Ball X == " + ballx, 5, 20);
        g.drawString("Ball Y == " + bally, 5, 35);
        g.drawString("Old Ball X == " + oldballx, 5, 50);
        g.drawString("Old Ball Y == " + oldbally, 5, 65);        
        g.drawString(lineparamA+"x + " + lineparamB + "y + " + lineparamC +" = 0", 5, 80);
        if(directionx){
            g.drawString("X tang", 5, 95);
        }else{
            g.drawString("X giam", 5, 110);
        }
        if(directiony){
            g.drawString("Y tang", 5, 125);
        }else{
            g.drawString("Y giam", 5, 140);    
        }
        g.fillOval(ballx - ballradius, bally - ballradius, ballradius*2, ballradius*2);
        g.setColor(Color.WHITE);
        g.drawLine(ballx, bally, oldballx, oldbally);
    }

    public void run() {
        while(isrunning){
            try{
                Thread.sleep(10);
            }catch(Exception e){}

            if(isholding){
                if(System.currentTimeMillis() - starttime >= 100){
                    starttime = System.currentTimeMillis() - 50;
                    createlinefuntion(ballx, bally, oldballx, oldbally);
                    oldballx = ballx;
                    oldbally = bally;
                }
            }
            if(isshoted){
                currenttime = (System.currentTimeMillis() - shottime) * 0.01;                
                if(velocity > 0){
                    velocity = velocitypower + acceleration * currenttime;
//                    if(direction){
                        if(directionx)
                            ballx += velocity;
//                            ballx ++;
                        else
                            ballx -= velocity;
//                         ballx --;
//                        bally = recalculatey(ballx);
//                    }else{
                        if(directiony)
                            bally += velocity;
//                            bally ++;
                        else
                            bally -= velocity;
//                            bally --;
                        
//                        ballx = recalculatex(bally);
//                    }

                    if((ballx - ballradius) <= 0)
                        directionx = true;
                    else if((ballx + ballradius) >= getWidth())
                        directionx = false;
                    if((bally - ballradius) <= 0)
                        directiony = true;
                    else if((bally + ballradius) >= getHeight())
                        directiony = false;
                }
            }
            repaint();
        }
    }

    public void mouseClicked(MouseEvent e) {        
    }

    public void mousePressed(MouseEvent e) {
        if((int)(Math.sqrt((double)((e.getX() - ballx)*(e.getX() - ballx)+(e.getY()- bally)*(e.getY()- bally)))) <= ballradius){
            isholding = true;
            isshoted = false;
            holddistancex = e.getX() - ballx;
            holddistancey = e.getY() - bally;
            starttime = System.currentTimeMillis();
            oldballx = ballx;
            oldbally = bally;
        }
        if(e.getButton() == MouseEvent.BUTTON3){
            ballx = e.getX();
            bally = e.getY();
            isshoted = false;
            isholding = false;
            repaint();            
        }
    }

    public void mouseReleased(MouseEvent e) {
        if(isholding){            
            velocitypower = Math.sqrt((double)((ballx - oldballx)*(ballx - oldballx)+(bally - oldbally)*(bally - oldbally)));
            velocityangle = Math.atan2((ballx - oldballx), (bally - oldbally));
            velocityangle += Math.toRadians(90);
            acceleration = (-1)*(velocitypower/(System.currentTimeMillis() - starttime));
            velocity = velocitypower;
            createlinefuntion(ballx, bally, oldballx, oldbally);
//            createlinefuntion(ballx, bally, 0, 0);
            if(Math.abs(ballx - oldballx)>Math.abs(bally - oldbally)){
                direction = true;
                if(ballx > oldballx)
                    directionx = true;
                else
                    directionx = false;
            }else{
                direction = false;
                if(bally > oldbally)
                    directiony = true;
                else
                    directiony = false;
            }
            if((lineparamA != 0)&&(lineparamB!=0)&&(lineparamC!=0)){
                isshoted = true;
                isholding = false;
                shottime = System.currentTimeMillis();
            }
        }        
    }

    public void mouseEntered(MouseEvent e) {
        isrunning =true;
    }

    public void mouseExited(MouseEvent e) {
        isrunning = false;
    }

    public void mouseDragged(MouseEvent e) {
        if(isholding){
            ballx = e.getX() - holddistancex;
            bally = e.getY() - holddistancey;            
        }        
        repaint();
    }

    public void mouseMoved(MouseEvent e) {
        
    }

}
